package com.taoge.biz.server;

import com.taoge.biz.common.constant.SmsConstant;
import com.taoge.biz.common.enums.SmsActionType;
import com.taoge.biz.common.enums.errorCode.VerifyCodeErrorCodeEnum;
import com.taoge.biz.persistent.entity.VerifyCode;
import com.taoge.biz.persistent.service.SmsRecordService;
import com.taoge.biz.persistent.service.VerifyCodeService;
import com.taoge.biz.server.param.sms.SendSmsCodeParam;
import com.taoge.framework.exception.BaseException;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @ClassName: com.taoge.biz.server
 * @Description: 发送验证码
 * @Author: YaoSiCheng
 * @Date: 2024-06-05 17:21
 **/
@Service
public class VerifyCodeServer {

    @Resource
    SmsServer smsServer;

    @Resource
    SmsRecordService smsRecordService;

    @Resource
    VerifyCodeService verifyCodeService;

    /**
     * 短信验证码长度 一般4-6位可以放到配置文件中
     */
    private static final int SMS_CODE_LENGTH = 4;

    /**
     * 短信验证码生效时间 3分钟
     */
    private static final long SMS_CODE_EXPIRE = 3 * 60 * 1000L;

    /**
     * 短信一天发送几条
     */
    private static final int SMS_CODE_MAX_COUNT_DAY = 5;

   /**
    * @title: sendSmsCode
    * @description: 发送短信验证码
    * @date:   2024-06-17 16:20:43
    * @author: YaoSiCheng
    * @param:  userId
    * @param:  originalMobile
    * @param:  mobilePrefix
    * @param:  iso
    * @param:  actionType 业务类型
    * @param:  templateCode
    * @param:  templateParam
    * @param:  ip
    * @return: void
    */
   public void sendSmsCode(SendSmsCodeParam param) {
       // 当期用户、当前手机号、当前业务，是否已经发送过
       VerifyCode verifyCode = verifyCodeService.selectValidCode(param.getUserId(), param.getMobilePrefix() + param.getOriginMobile(), param.getActionType());
       if (verifyCode != null) {
           // 验证码还没过期
           if (verifyCode.getExpireTime().getTime() > System.currentTimeMillis()) {
               // 还有多少秒后过期
               long s = (verifyCode.getExpireTime().getTime() - System.currentTimeMillis()) / 1000;
               throw new BaseException(VerifyCodeErrorCodeEnum.SMS_CODE_SEND.getCode(), VerifyCodeErrorCodeEnum.SMS_CODE_SEND.getMsg() + "，请" + s + "s后重试");
           }
       }
        /*
       // 验证短信发送限制（当前小时次数、当前次数、总次数）
       Long smsCount = smsRecordService.countByMobileInDay(param.getUserId(), param.getMobilePrefix() + param.getOriginalMobile(), param.getActionType());
       // 判断当天发送短信次数是否超过上限
       if (smsCount > SMS_CODE_MAX_COUNT_DAY) {
           throw new BaseException(SmsErrorCodeEnum.SEND_SMS_DAY_MAX_COUNT_ERROR.getCode(),
                    SmsErrorCodeEnum.SEND_SMS_DAY_MAX_COUNT_ERROR.getMsg());
       }*/

       //短信安全校验
       smsServer.validateSmsInfo(param);

       //生成验证码
       String code = generateSmsCode();
       //保存验证码
       saveVerifyCode(param.getUserId(), param.getMobilePrefix() + param.getOriginMobile(), code, param.getActionType());
       smsServer.sendSmsCode(param, code);

   }

    /**
     * @title: generateSmsCode
     * @description: 生成短信验证码
     * @date:   2024-06-17 15:48:13
     * @author: YaoSiCheng
     * @param:
     * @return: String
     */
    private String generateSmsCode() {
        // 测试环境直接返回
        if(SmsConstant.isEnvDev()){
            return "1234";
        }
        // 随机4位数字
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < SMS_CODE_LENGTH; i++) {
            code.append(RandomUtils.nextInt(0,10));
        }
        return code.toString();
    }

    /**
     * @title: saveVerifyCode
     * @description: 保存验证码
     * @date: 2024-07-01 09:54:40
     * @author: YaoSiCheng
     * @param: userId
     * @param: mobile
     * @param: code
     * @param: actionType
     * @return: void
     */
    private void saveVerifyCode(Long userId, String mobile, String code, SmsActionType actionType) {
        // 保存验证码之前将之前数据改为失效
        // verifyCodeService.updateExpireCode(userId, mobile, actionType);
        VerifyCode verifyCode = new VerifyCode();
        verifyCode.setUserId(userId);
        verifyCode.setMobile(mobile);
        verifyCode.setCode(code);
        verifyCode.setActionType(actionType.name());
        verifyCode.setFailCount(0);
        verifyCode.setExpireTime(generateSmsCodeExpireTime());
        verifyCodeService.save(verifyCode);
    }

    /**
     * @title: generateSmsCodeExpireTime
     * @description: 获取失效时间
     * @date: 2024-07-01 09:54:55
     * @author: YaoSiCheng
     * @param:
     * @return: Date
     */
    private Date generateSmsCodeExpireTime() {
        // 3分钟过期
        return new Date(System.currentTimeMillis() + SMS_CODE_EXPIRE);
    }
}
